﻿#include "uimodbusbase.h"

#include <QHeaderView>
#include <QPushButton>
#include <QHBoxLayout>

#include "shlib/viewmodel/ctablemodel.h"
#include "shlib/viewmodel/uifieldsearchwidget.h"
#include "shlib/viewmodel/cfiltermodel.h"
#include "shlib/viewmodel/ctabledelegate.h"
#include "protocol/modbus/cmodbusunitcoil.h"

#include <shlib/quc_sdk/iconhelper/icon_helper.h>
#include <shlib/cwebrequestapi.h>
#include <shlib/csigmanager.h>

#include <ElaTableView.h>
#include <ElaMessageBar.h>

UiModbusBase::UiModbusBase(ESigType type, QWidget *parent)
    : QWidget{parent},m_type(type)
{
    this->setWindowFlags(Qt::FramelessWindowHint);
    this->setStyleSheet("background-color: rgba(0, 0, 0, 0);");

    IconHelper* iconsMgr = IconHelper::instance();
    m_model = new CTableModel(this);

    CTableDelegate* delegate = new CTableDelegate(this);

    m_filterModel = new CFilterModel(this);
    m_filterModel->setSourceModel(m_model);

    m_view = new ElaTableView(this);
    m_view->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    m_view->setModel(m_filterModel);
    m_view->setItemDelegate(delegate);
    m_view->setAlternatingRowColors(true);
    m_view->verticalHeader()->setHidden(true);

    m_searchWidget = new UiFieldSearchWidget(this);
    m_searchWidget->searchBox()->setMinimumHeight(30);

    if( ESigType::EYc==m_type || ESigType::EParameter==m_type) {
        m_searchWidget->setFields(QStringList() <<"信号名字"<< "寄存器类型" << "寄存器地址" << "数据长度" << "数据类型");
    } else {
        m_searchWidget->setFields(QStringList() <<"信号名字"<< "寄存器类型" << "寄存器地址" << "是否bit" << "bit偏移");
    }

    // 初始化清空搜索按钮，并连接点击事件
    m_clearSearchBtn = new ElaIconButton(ElaIconType::Broom,this);
    m_clearSearchBtn->setMinimumHeight(30);
    m_clearSearchBtn->setBorderRadius(2);
    connect(m_clearSearchBtn,&QPushButton::clicked,this,[=](){
        m_filterModel->applyFilter("","");
        m_searchWidget->clearSearch();
    });

    m_saveBtn = new ElaIconButton(ElaIconType::FileCheck,this);
    m_saveBtn->setText("提交更改");
    m_saveBtn->setEnabled(false);


    m_resaveBtn = new ElaIconButton(ElaIconType::FileXmark,this);
    m_resaveBtn->setText("恢复更改");
    m_resaveBtn->setEnabled(false);

    QHBoxLayout* topLayout = new QHBoxLayout;
    topLayout->addWidget(m_searchWidget);
    topLayout->addWidget(m_clearSearchBtn);
    topLayout->addStretch(1);
    topLayout->addWidget(m_resaveBtn);
    topLayout->addWidget(m_saveBtn);

    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    mainLayout->addLayout(topLayout);
    mainLayout->addWidget(m_view);

    // 连接搜索信号，执行搜索逻辑
    connect(m_searchWidget,&UiFieldSearchWidget::sigSearch,this,[=](const QString& fieldName,const QString& searchText){
        m_filterModel->applyFilter(fieldName,searchText);
    });

    connect(CSigMgr, &CSigManager::modbusMapSigChange, this, &UiModbusBase::slotModbusMapSigChange);
    connect(m_saveBtn, &ElaIconButton::clicked, this, &UiModbusBase::slotSaveChange);
}

void UiModbusBase::slotSelectMapChange(const QString &userid, const QString &modelName, const QString &mapid)
{
    m_userid = userid;
    m_modelid = modelName;
    m_mapid = mapid;

    m_model->removeAllData();

    if(m_mapid.isEmpty())
        return;

    QList<QSharedPointer<IModel>> sigmaps;

    if(m_type == ESigType::EYx) {
        if(!CWebRequestApi::ins().getModbusMapYxs(m_userid, m_modelid, m_mapid, sigmaps)) {

        }
    } else if(m_type == ESigType::EYk) {
        if(!CWebRequestApi::ins().getModbusMapYks(m_userid, m_modelid, m_mapid, sigmaps)) {

        }
    } else if(m_type == ESigType::EYc) {
        if(!CWebRequestApi::ins().getModbusMapYcs(m_userid, m_modelid, m_mapid, sigmaps)) {

        }
    } else if(m_type == ESigType::EParameter) {
        if(!CWebRequestApi::ins().getModbusMapParameters(m_userid, m_modelid, m_mapid, sigmaps)) {

        }
    }
    for(auto& it : sigmaps) {
        m_model->appendData(it);
    }
}

void UiModbusBase::slotModbusMapSigChange(QString name, ESigType sigtype) {
    if(m_type != sigtype)
        return;

    m_changeRows.insert(name, -1);
    m_saveBtn->setEnabled(true);
    m_resaveBtn->setEnabled(true);
}

void UiModbusBase::slotSaveChange() {
    QMap<QString, QSharedPointer<IModel>> sigmaps;
    for(int row = 0; row < m_model->rowCount(); ++row) {
        QSharedPointer<IModel> value = m_model->getDataByIndex(row);
        QString signame = value->getFieldValueByFielddName("信号名字").toString();
        if(m_changeRows.contains(signame)) {
            m_changeRows[signame] = row;
            sigmaps[signame] = value;
        }
    }

    if(m_type == ESigType::EYx) {
        for(auto& it : sigmaps) {
            CModbusUnitCoil* yxptr = static_cast<CModbusUnitCoil*>(it.data());
            if( EOptType::EChange == yxptr->opt_type || EOptType::EAdd == yxptr->opt_type) {
                if(!yxptr->checkData()) {
                    ElaMessageBar::error(ElaMessageBarType::Top, "错误", QString("信号:'%1'数据校验失败，请检查后重新提交").arg(yxptr->name),2000);
                    return;
                }
            }
        }

        if(!CWebRequestApi::ins().changeModbusMapYxs(m_mapid, sigmaps)) {
            ElaMessageBar::warning(ElaMessageBarType::Top, "警告", QString("服务器请求失败,请稍后尝试！"),2000);
            return;
        }

        for(auto& it : sigmaps) {
            CModbusUnitCoil* yxptr = static_cast<CModbusUnitCoil*>(it.data());
            if( EOptType::EDelete ==  yxptr->opt_type) {
                m_model->removeData(m_changeRows[yxptr->name]);
            }
        }

    } else if(m_type == ESigType::EYk) {
        for(auto& it : sigmaps) {
            CModbusUnitCoil* ykptr = static_cast<CModbusUnitCoil*>(it.data());
            if( EOptType::EChange == ykptr->opt_type || EOptType::EAdd == ykptr->opt_type) {
                if(!ykptr->checkData()) {
                    ElaMessageBar::error(ElaMessageBarType::Top, "错误", QString("信号:'%1'数据校验失败，请检查后重新提交").arg(ykptr->name),2000);
                    return;
                }
            }
        }

        if(!CWebRequestApi::ins().changeModbusMapYks(m_mapid, sigmaps)) {
            ElaMessageBar::warning(ElaMessageBarType::Top, "警告", QString("服务器请求失败,请稍后尝试！"),2000);
            return;
        }

        for(auto& it : sigmaps) {
            CModbusUnitCoil* ykptr = static_cast<CModbusUnitCoil*>(it.data());
            if( EOptType::EDelete ==  ykptr->opt_type) {
                m_model->removeData(m_changeRows[ykptr->name]);
            }
        }
    } else if(m_type == ESigType::EYc) {
        for(auto& it : sigmaps) {
            CModbusUnitRegister* ycptr = static_cast<CModbusUnitRegister*>(it.data());
            if( EOptType::EChange == ycptr->opt_type || EOptType::EAdd == ycptr->opt_type) {
                if(!ycptr->checkData()) {
                    ElaMessageBar::error(ElaMessageBarType::Top, "错误", QString("信号:'%1'数据校验失败，请检查后重新提交").arg(ycptr->name),2000);
                    return;
                }
            }
        }

        if(!CWebRequestApi::ins().changeModbusMapYcs(m_mapid, sigmaps)) {
            ElaMessageBar::warning(ElaMessageBarType::Top, "警告", QString("服务器请求失败,请稍后尝试！"),2000);
            return;
        }

        for(auto& it : sigmaps) {
            CModbusUnitRegister* ycptr = static_cast<CModbusUnitRegister*>(it.data());
            if( EOptType::EDelete ==  ycptr->opt_type) {
                m_model->removeData(m_changeRows[ycptr->name]);
            }
        }
    } else if(m_type == ESigType::EParameter) {
        for(auto& it : sigmaps) {
            CModbusUnitRegister* parameterptr = static_cast<CModbusUnitRegister*>(it.data());
            if( EOptType::EChange == parameterptr->opt_type || EOptType::EAdd == parameterptr->opt_type) {
                if(!parameterptr->checkData()) {
                    ElaMessageBar::error(ElaMessageBarType::Top, "错误", QString("信号:'%1'数据校验失败，请检查后重新提交").arg(parameterptr->name),2000);
                    return;
                }
            }
        }

        if(!CWebRequestApi::ins().changeModbusMapParameters(m_mapid, sigmaps)) {
            ElaMessageBar::warning(ElaMessageBarType::Top, "警告", QString("服务器请求失败,请稍后尝试！"),2000);
            return;
        }

        for(auto& it : sigmaps) {
            CModbusUnitRegister* parameterptr = static_cast<CModbusUnitRegister*>(it.data());
            if( EOptType::EDelete ==  parameterptr->opt_type) {
                m_model->removeData(m_changeRows[parameterptr->name]);
            }
        }
    }
    m_changeRows.clear();
    ElaMessageBar::information(ElaMessageBarType::Top, "提示", QString("修改成功"),2000);
    m_saveBtn->setEnabled(false);
    m_resaveBtn->setEnabled(false);
    return;
}

void UiModbusBase::slotRecoverChange()
{

}
